package concordia.comp6231.server;
import java.io.*;
import java.net.*;

import concordia.comp6231.model.Show;


class ExchangeUDPServer extends Thread {
	
	private int port;
	private DatagramSocket serverSocket;
	private BoxOfficeImpl boxOfficeImpl;
	
	public ExchangeUDPServer(int port, BoxOfficeImpl boxOfficeImpl) {
		this.port = port;
		this.boxOfficeImpl = boxOfficeImpl;
	}
    
	public void run() {
		System.out.println("Exchange UDP Server running and waiting...");
		byte[] receiveData = new byte[1024];
		try {
			serverSocket = new DatagramSocket(port);
			while (true) {
				DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
			    serverSocket.receive(receivePacket);
				System.out.println("RECEIVED: " + new String(receivePacket.getData()));
			    new RequestHandler(serverSocket, receivePacket).start();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
    
	class RequestHandler extends Thread {
		DatagramSocket socket = null;
	    DatagramPacket packet = null;
	    public RequestHandler(DatagramSocket socket, DatagramPacket packet) {
	        this.socket = socket;
	        this.packet = packet;
	    }

	    public void run() {
	        byte[] data = createResponse();
	        DatagramPacket response = new DatagramPacket(data, data.length, packet.getAddress(), packet.getPort());
	        try {
				socket.send(response);
			} catch (IOException e) {
				e.printStackTrace();
			}
	    }
	    
	    private byte[] createResponse() {
	    	String response = "";
	    	// txID: action-000001-MTL001-5-QUE001-2
	    	String transactionID = new String(packet.getData());
	    	String[] tockens =  transactionID.split("-");
	    	String action = tockens[0].trim();
			String customerID = tockens[1].trim();
			String desiredShowID = tockens[4].trim();
			int desiredTickets = Integer.parseInt(tockens[5].trim());
			if ("canExchange".equals(action)) {
				// 4- QUE: checks if show QUE001 has 2 available tickets
				if (!ExchangeUDPServer.this.boxOfficeImpl.showExists(desiredShowID)) {
					response = "ERROR: Desired Show ID does not exist.";					
				} else {
					Show desiredShow = ExchangeUDPServer.this.boxOfficeImpl.getShow(desiredShowID);
					if (desiredShow.getAvailableTicketsCount() < desiredTickets) {
						response = "ERROR: Available tickets for desired Show is smaller than desired tickets";
					} else {
						// 5- QUE: reserve 2 tickets
						ExchangeUDPServer.this.boxOfficeImpl.reserve(customerID, desiredShowID, desiredTickets);
						// 6- QUE: send UPD packet to MTL to acknowledge
						response = "canExchange: " + transactionID;
					}				
				}
			} else if ("rollBack".equals(action)) {
				ExchangeUDPServer.this.boxOfficeImpl.cancel(customerID, desiredShowID, desiredTickets);
				response = "rollBack_SUCCESS: " + transactionID;
			} else {
				response = "ERROR: Invalid action: " + action;
			}
			return response.getBytes();
	    }
	    
	}
	
}